fix: honor init container order in spec.deployment.patch [RHDHBUGS-2900]#2824
Conversation
Use ListIncreaseDirection: MergeOptionsListPrepend so user-specified init containers are prepended rather than appended, allowing them to run before install-dynamic-plugins. Assisted-by: Claude
…GS-2900] Add TestInitContainerOrderInSpecDeployment to verify user-specified init containers are prepended before install-dynamic-plugins. Update existing TestMergeFromSpecDeployment assertions to match prepend behavior. Document list ordering semantics in docs/configuration.md. Assisted-by: Claude
…S-2900] Show how to place a custom init container after install-dynamic-plugins by referencing the existing container by name first in the patch. Assisted-by: Claude
…BUGS-2900] Cover both ordering directions in TestInitContainerOrderInSpecDeployment: prepending before and anchoring after install-dynamic-plugins. Assisted-by: Claude
…HDHBUGS-2900] kyaml's merge2 silently ignores $patch directives (e.g. $patch: replace) when ListIncreaseDirection is set to ListPrepend. Work around this by doing a second merge pass with default options to apply $patch directives, after the first pass has already established correct list item positions. Assisted-by: Claude
Code Review by Qodo
Context used 1. Double merge every reconcile
|
…-deployment-patch-does-not-honor-the-order-of-init-containers-install-dynamic-plugins-always-runs-first
|
/cc @gazarenkov |
Review Summary by QodoHonor init container order in spec.deployment.patch with two-pass merge
WalkthroughsDescription• Implement two-pass merge strategy to honor init container ordering in spec.deployment.patch - Pass 1 uses ListPrepend to prepend new list items before existing ones - Pass 2 applies $patch directives to preserve special merge semantics • Add comprehensive test coverage for init container ordering scenarios - Tests prepending before existing containers - Tests anchoring to place containers after existing ones - Tests multiple containers with mixed ordering • Document list ordering semantics and provide usage examples - Explain prepend behavior for new list items - Show workaround to anchor containers after existing ones by name reference Diagramflowchart LR
A["User Patch"] -->|Pass 1: ListPrepend| B["Correct List Order"]
B -->|Pass 2: Default Options| C["Final Merged Deployment"]
C -->|Result| D["New containers before existing<br/>$patch directives applied"]
File Changes1. pkg/model/deployment.go
|
…t-honor-the-order-of-init-containers-install-dynamic-plugins-always-runs-first
… [RHDHBUGS-2900] Recommend listing all init containers explicitly in the desired order, and note that $setElementOrder is not supported by the kyaml library. Co-authored-by: Gennady Azarenkov <gazarenkov@gmail.com> Assisted-by: Claude
…t-honor-the-order-of-init-containers-install-dynamic-plugins-always-runs-first
|
|
/cherry-pick release-1.10 |
|
@rm3l: once the present PR merges, I will cherry-pick it on top of DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
Welcome to Codecov 🎉Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests. Thanks for integrating Codecov - We've got you covered ☂️ |
| // remove this two-pass merge and use only ListPrepend. | ||
| // | ||
| // RHDHBUGS-2900: Two-pass merge to work around a kyaml bug where ListPrepend | ||
| // silently breaks $patch directives (e.g. $patch: replace). |
There was a problem hiding this comment.
I could not reproduce this bug (tried with single MergeStrings and it worked with directives as well). What exactly is your config to reproduce?
| assert.Equal(t, 2, len(model.backstageDeployment.podSpec().Containers)) | ||
| assert.Equal(t, "sidecar", model.backstageDeployment.podSpec().Containers[1].Name) | ||
| assert.Equal(t, "my-image:1.0.0", model.backstageDeployment.podSpec().Containers[1].Image) | ||
| assert.Equal(t, "sidecar", model.backstageDeployment.podSpec().Containers[0].Name) |
There was a problem hiding this comment.
This looks like breaking change for users relying on certain order (appended logic).
We should at least document it (however I do not think we have it documented anywhere, so probably just Release Notes) or even think about additional conf flag like:
spec.deployment.mergeListMode: [append]|prepend
?



Description
spec.deployment.patchdid not allow users to control the ordering of init containers. New init containers would always be appended after existing ones (e.g.,install-dynamic-pluginsalways ran first).This PR switches the
kyamlmerge strategy so new list items are prepended before existing ones by default. Users who need a custom init container to run after an existing one can still anchor it by referencing the existing container by name first in the patch (this didn't work with the default merge strategy).Which issue(s) does this PR fix or relate to
PR acceptance criteria
How to test changes / Special notes to the reviewer
Note that a two-pass merge is used here to work around kubernetes-sigs/kustomize#6146, where the prepend strategy silently breaks
$patchdirectives. Once that issue is fixed in kyaml, we'll be able to remove this two-pass merge and only use the Prepend strategy.